<template>
    <Mapbox :mapOnLoadCB="mapOnLoadCB"></Mapbox>
    <div class='overlay'>
        <button id='replay'>Replay</button>
    </div>
</template>

<script>
import {ref} from "vue"
import Mapbox from "@/components/common/Mapbox.component.vue"
import MapboxCommonService from "@/service/map/MapboxCommonService"

export default {
    name: "SymbolFly.component",
    components: {Mapbox},
    setup() {

        let origin = [-122.414, 37.776]
        // A simple line from origin to destination.
        let route = {
            "type": "FeatureCollection",
            "features": [{
                "type": "Feature",
                "geometry": {
                    "type": "LineString",
                    "coordinates": [origin, [-77.032, 38.913]]
                }
            }]
        };

        // A single point that animates along the route.
        // Coordinates are initially set to origin.
        let point = {
            "type": "FeatureCollection",
            "features": [{
                "type": "Feature",
                "properties": {},
                "geometry": {
                    "type": "Point",
                    "coordinates": origin
                }
            }]
        };

        // Calculate the distance in kilometers between route start/end point.
        let lineDistance = turf.lineDistance(route.features[0], 'kilometers');

        let arc = [];

        // Number of steps to use in the arc and animation, more steps means
        // a smoother arc and animation, but too many steps will result in a
        // low frame rate
        let steps = 500;

        // Draw an arc between the `origin` & `destination` of the two points
        for (let i = 0; i < lineDistance; i += lineDistance / steps) {
            let segment = turf.along(route.features[0], i, 'kilometers');
            arc.push(segment.geometry.coordinates);
        }

        // Update the route with calculated arc coordinates
        route.features[0].geometry.coordinates = arc;

        // Used to increment the value of the point measurement against the route.
        let counter = 0;

        let mapStore = ref({});
        let mapOnLoadCB = (map) => {
            mapStore.value = map;
            MapboxCommonService.setCZBP(map, [-96, 37.8], 3)

            // 使用 Turf 平滑地沿指定路线为点设置动画效果。
            // Add a source and layer displaying a point which will be animated in a circle.
            map.addSource('route', {
                "type": "geojson",
                "data": route
            });

            map.addSource('point', {
                "type": "geojson",
                "data": point
            });

            map.addLayer({
                "id": "route",
                "source": "route",
                "type": "line",
                "paint": {
                    "line-width": 2,
                    "line-color": "#007cbf"
                }
            });

            map.addLayer({
                "id": "point",
                "source": "point",
                "type": "symbol",
                "layout": {
                    "icon-image": "airport-15",
                    "icon-rotate": ["get", "bearing"],
                    "icon-rotation-alignment": "map",
                    "icon-allow-overlap": true,
                    "icon-ignore-placement": true
                }
            });

            const animate = () => {
                // Update point geometry to a new position based on counter denoting
                // the index to access the arc.
                point.features[0].geometry.coordinates = route.features[0].geometry.coordinates[counter];

                // Calculate the bearing to ensure the icon is rotated to match the route arc
                // The bearing is calculate between the current point and the next point, except
                // at the end of the arc use the previous point and the current point
                point.features[0].properties.bearing = turf.bearing(
                    turf.point(route.features[0].geometry.coordinates[counter >= steps ? counter - 1 : counter]),
                    turf.point(route.features[0].geometry.coordinates[counter >= steps ? counter : counter + 1])
                );

                // Update the source with this new data.
                map.getSource('point').setData(point);

                // Request the next frame of animation so long the end has not been reached.
                if (counter < steps) {
                    requestAnimationFrame(animate);
                }

                counter = counter + 1;
            }

            document.getElementById('replay').addEventListener('click', function () {
                // Set the coordinates of the original point back to origin
                point.features[0].geometry.coordinates = origin;

                // Update the source layer
                map.getSource('point').setData(point);

                // Reset the counter
                counter = 0;

                // Restart the animation.
                animate(counter);
            });

            // Start the animation.
            // animate(counter);
        };

        return {
            mapOnLoadCB
        }
    }
}
</script>

<style scoped lang="scss">
.overlay {
    position: absolute;
    top: 10px;
    left: 10px;
}
.overlay button {
    font: 600 12px/20px 'Helvetica Neue', Arial, Helvetica, sans-serif;
    background-color: #3386c0;
    color: #fff;
    display: inline-block;
    margin: 0;
    padding: 10px 20px;
    border: none;
    cursor: pointer;
    border-radius: 3px;
}
.overlay button:hover {
    background-color: #4ea0da;
}
</style>